/**
 * LocalCache - 基于localforage的扩展实现，支持数据过期时间
 * 依赖: localforage.js
 */

// 确保localforage已加载
if (typeof localforage === 'undefined') {
    console.error('LocalCache 依赖 localforage.js，请先引入该库');
}

const LocalCache = (function() {
    // 默认过期时间设置 (毫秒)
    const DEFAULT_EXPIRY = 30 * 24 * 60 * 60 * 1000; // 30天
    
    // 配置 localforage 实例
    const storage = localforage.createInstance({
        driver: localforage.LOCALSTORAGE,
        name: 'wemedia',
        version: 1.0,
        storeName: 'bbscache',
        description: '带过期时间的本地缓存'
    });
    
    /**
     * 设置带过期时间的缓存项
     * @param {string} key - 缓存键
     * @param {any} value - 要存储的值
     * @param {number} [expiryMs] - 过期时间(毫秒)，默认30天
     * @returns {Promise<any>} - Promise对象，解析为存储的值
     */
    async function setItem(key, value, expiryMs = DEFAULT_EXPIRY) {
        if (!key) {
            throw new Error('缓存键不能为空');
        }
        
        // 包装数据，添加过期时间戳
        const item = {
            value: value,
            expires: Date.now() + expiryMs,
            createdAt: Date.now()
        };
        
        try {
            await storage.setItem(key, item);
            return value;
        } catch (err) {
            console.error(`缓存项 ${key} 设置失败:`, err);
            throw err;
        }
    }
    
    /**
     * 获取缓存项，如果已过期则返回null
     * @param {string} key - 缓存键
     * @param {any} [defaultValue] - 如果项不存在或已过期时的默认值
     * @returns {Promise<any>} - Promise对象，解析为存储的值或默认值
     */
    async function getItem(key, defaultValue = null) {
        if (!key) {
            return defaultValue;
        }
        
        try {
            const item = await storage.getItem(key);
            
            // 如果项不存在，返回默认值
            if (item === null) {
                return defaultValue;
            }
            
            // 如果数据格式不正确，返回默认值
            if (!item.value || !item.expires) {
                console.warn(`缓存项 ${key} 格式不正确`);
                await storage.removeItem(key); // 清除无效数据
                return defaultValue;
            }
            
            // 检查是否过期
            if (Date.now() > item.expires) {
                console.log(`缓存项 ${key} 已过期`);
                await storage.removeItem(key); // 清除过期数据
                return defaultValue;
            }
            
            return item.value;
        } catch (err) {
            console.error(`获取缓存项 ${key} 失败:`, err);
            return defaultValue;
        }
    }
    
    /**
     * 删除缓存项
     * @param {string} key - 缓存键
     * @returns {Promise<void>}
     */
    async function removeItem(key) {
        if (!key) return;
        
        try {
            await storage.removeItem(key);
        } catch (err) {
            console.error(`删除缓存项 ${key} 失败:`, err);
            throw err;
        }
    }
    
    /**
     * 获取缓存项的剩余有效时间(毫秒)
     * @param {string} key - 缓存键
     * @returns {Promise<number|null>} - 剩余毫秒数，如果项不存在或已过期则返回null
     */
    async function getTimeToLive(key) {
        if (!key) return null;
        
        try {
            const item = await storage.getItem(key);
            
            // 如果项不存在或格式不正确
            if (!item || !item.expires) {
                return null;
            }
            
            const ttl = item.expires - Date.now();
            return ttl > 0 ? ttl : null;
        } catch (err) {
            console.error(`获取缓存项 ${key} 的TTL失败:`, err);
            return null;
        }
    }
    
    /**
     * 刷新缓存项的过期时间
     * @param {string} key - 缓存键
     * @param {number} [expiryMs] - 新的过期时间(毫秒)，默认1天
     * @returns {Promise<boolean>} - 是否成功刷新
     */
    async function refreshExpiry(key, expiryMs = DEFAULT_EXPIRY) {
        if (!key) return false;
        
        try {
            const item = await storage.getItem(key);
            
            // 如果项不存在或格式不正确
            if (!item || !item.value) {
                return false;
            }
            
            // 更新过期时间
            item.expires = Date.now() + expiryMs;
            await storage.setItem(key, item);
            return true;
        } catch (err) {
            console.error(`刷新缓存项 ${key} 过期时间失败:`, err);
            return false;
        }
    }
    
    /**
     * 清理所有过期的缓存项
     * @returns {Promise<number>} - 清理的项数量
     */
    async function clearExpired() {
        let count = 0;
        
        try {
            await storage.iterate((value, key) => {
                if (value && value.expires && Date.now() > value.expires) {
                    storage.removeItem(key);
                    count++;
                }
            });
            
            return count;
        } catch (err) {
            console.error('清理过期缓存项失败:', err);
            throw err;
        }
    }
    
    /**
     * 清除所有缓存
     * @returns {Promise<void>}
     */
    async function clear() {
        try {
            await storage.clear();
        } catch (err) {
            console.error('清除所有缓存失败:', err);
            throw err;
        }
    }
    
    /**
     * 获取所有缓存项的键
     * @returns {Promise<string[]>}
     */
    async function keys() {
        try {
            return await storage.keys();
        } catch (err) {
            console.error('获取缓存键列表失败:', err);
            throw err;
        }
    }
    
    /**
     * 获取缓存统计信息
     * @returns {Promise<Object>} - 包含总数、有效项数、过期项数等信息
     */
    async function getStats() {
        let total = 0;
        let expired = 0;
        let valid = 0;
        let size = 0;
        
        try {
            await storage.iterate((value, key) => {
                total++;
                
                // 估算大小（粗略计算）
                const itemSize = JSON.stringify(value).length;
                size += itemSize;
                
                if (value && value.expires) {
                    if (Date.now() > value.expires) {
                        expired++;
                    } else {
                        valid++;
                    }
                }
            });
            
            return {
                total,
                valid,
                expired,
                size: `${(size / 1024).toFixed(2)} KB`
            };
        } catch (err) {
            console.error('获取缓存统计信息失败:', err);
            throw err;
        }
    }
    
    /**
     * 设置默认过期时间
     * @param {number} ms - 毫秒数
     */
    function setDefaultExpiry(ms) {
        if (typeof ms !== 'number' || ms <= 0) {
            throw new Error('默认过期时间必须为正数');
        }
        DEFAULT_EXPIRY = ms;
    }
    
    // 定期清理过期项（每小时一次）
    setInterval(clearExpired, 60 * 60 * 1000);
    
    // 公开API
    return {
        setItem,
        getItem,
        removeItem,
        getTimeToLive,
        refreshExpiry,
        clearExpired,
        clear,
        keys,
        getStats,
        setDefaultExpiry
    };
})();


// 导出API
window.LocalCache = LocalCache;

